﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Medianamik.Core.Sugar;
using Medianamik.Globalization;
using System.Web.UI;
using System.Web.Security;
using Medianamik.Core.Security;
using System.Globalization;
using Medianamik.Core.Profile;
using System.Threading;
using Medianamik.Core;
using System.Collections.ObjectModel;
using Telerik.Web.UI;
using Medianamik.Core.Configuration;
using System.Configuration;
using Roles = Medianamik.Core.Security.Roles;

namespace Medianamik.UI
{
    /// <summary>
    /// Classe de base des pages de Médianamik
    /// </summary>
    public abstract class BasePage : Page
    {
        const string PostBackEventTarget = "__EVENTTARGET";
        const string PostBackEventArgument = "__EVENTARGUMENT";

        private static readonly MedianamikConfigSection Config = (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);

        protected override void OnPreInit(EventArgs e)
        {
            if (AuthenticatedPage)
            {
                var url = "";

                if (User.Identity.IsAuthenticated
                    && MedianamikUser != null /* Vérifie que le user authtifié provient du MembershipProvider de Medianamik */)
                {
                    if (Roles.GetAllRoles().Any(r => r.EqualsIgnoreCase("medianamik")) &&
                        !Roles.UserIsSA() && !Roles.IsUserInRole(MedianamikRoles.Medianamik))
                    {
                        Response.StatusCode = 403;
                        url = "/medianamik/login.aspx";
                        //Response.End();
                    }
                        //TODO : Rediriger vers une page indiquant que la page n'existe pas...
                    else if (SiteMap.CurrentNode == null)
                        url = "/medianamik/";
                }
                else
                {
                    url = FormsAuthentication.LoginUrl + "?ReturnURL=" + Server.UrlEncode(Request.RawUrl);
                }

                if (!url.IsNullOrEmpty())
                {
                    if (Page.IsCallback)
                    {
                        var script = string.Format("document.location.href = '{0}');", url);
                        ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "redirect", script, true);
                    }
                    else
                    {
                        Response.Redirect(url);
                    }
                }
            }

            base.OnPreInit(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (Page.Header != null)
            {
                var control = Page.Header.FindControl("HeaderContentHolder");
                var headerText = String.Format(@"
                <link rel=""stylesheet"" type=""text/css"" media=""all"" href=""/Medianamik/includes/medianamik.css?v={0}"" />
                <link rel=""stylesheet"" type=""text/css"" media=""all"" href=""/Medianamik/includes/medianamik-custom.css?v={0}"" />
                <script type=""text/javascript"" src=""/Medianamik/includes/js/json2.js?v={0}""></script>                
                <script type=""text/javascript"" src=""/Medianamik/includes/js/jquery.js?v={0}""></script>                
                <script type=""text/javascript"" src=""/Medianamik/includes/js/site.js?v={0}""></script>
                <!-- (C) 2009 Absolunet inc. -->", Utility.GetFileVersion());

                if (control != null)
                {
                    int index = Page.Header.Controls.IndexOf(control);
                    Page.Header.Controls.AddAt(index, new LiteralControl(headerText));

                }
                else
                {
                    Page.Header.Controls.Add(new LiteralControl(headerText));
                }
            }
        }

        public event EventHandler<CultureChangedEventArgs> CultureChanged;

        protected virtual void OnCultureChanged(CultureChangedEventArgs e)
        {
            var handler = CultureChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        public RadWindowManager MyWindowManager
        {
            get { return (RadWindowManager)MyMasterPage.FindControl("radWindowManager"); }
        }

        public RadScriptBlock MyRadScriptBlock
        {
            get { return (RadScriptBlock)MyMasterPage.FindControl("radScriptBlock"); }
        }

        public RadScriptManager MyRadScriptManager
        {
            get { return (RadScriptManager)MyMasterPage.FindControl("radScriptManager"); }
        }

        public ScriptManager MyScriptManager
        {
            get
            {
                return ScriptManager.GetCurrent(Page);
            }
        }

        public RadAjaxManager MyRadAjaxManager
        {
            get { return (RadAjaxManager)MyMasterPage.FindControl("ajaxManager"); }
        }

        /// <summary>
        /// Détermine si l'usager doit ê authentifier pour afficher la page
        /// </summary>
        protected virtual bool AuthenticatedPage
        {
            get { return true; }
        }

        /// <summary>
        /// Langue courante de l'interface usager
        /// </summary>
        public String UIShortLang { get { return CurrentUICulture.TwoLetterISOLanguageName; } }

        public string ModuleTitle
        {
            get
            {
                var title = ViewState["ModuleTitle"] as string;

                if (title == null && SiteMap.CurrentNode != null)
                {
                    title = SiteMap.CurrentNode["moduleTitle"];
                    ViewState["ModuleTitle"] = title ?? string.Empty;
                }

                return title;
            }
        }

        public CultureInfo CurrentUICulture
        {
            get
            {
                return Thread.CurrentThread.CurrentUICulture;
            }
        }

        public virtual CultureInfo CurrentEditionCulture
        {
            get
            {
                if (CurrentPage.IsLanguageNeutral) { return CultureInfo.InvariantCulture; }
                if (EditionCultures.Count() == 1) { return EditionCultures.First().CultureInfo; }
                return MedianamikContext.Current.EditionCulture;
            }
            set
            {
                MedianamikContext.Current.EditionCulture = value;
                _webSites = null;
                _editionCultureHasChanged = true;
            }
        }

        public bool EditionCultureHasChanged
        {
            get { return _editionCultureHasChanged; }
        }
        bool _editionCultureHasChanged;

        private IEnumerable<Culture> _editionCultures;
        public virtual IEnumerable<Culture> EditionCultures
        {
            get
            {
                if (_editionCultures == null && !CurrentPage.IsLanguageNeutral)
                {
                    _editionCultures = ConfigManager.GetEditionCultures();
                }

                return _editionCultures;
            }
        }

        IEnumerable<string> _medianamikCultures;
        public IEnumerable<string> MedianamikCultures
        {
            get
            {
                if (_medianamikCultures == null)
                    _medianamikCultures = ConfigManager.
                        GetMedianamikCultures().Select(c => c.CultureName);

                return _medianamikCultures;
            }
        }

        private Collection<WebSite> _webSites;
        public Collection<WebSite> WebSites
        {
            get
            {
                if (_webSites == null)
                {
                    _webSites = ConfigManager.GetAllWebSites(CurrentEditionCulture);
                }

                return _webSites;
            }
        }

        private MedianamikModuleDTO _currentModule;
        public MedianamikModuleDTO CurrentModule
        {
            get
            {
                if (_currentModule == null)
                {
                    var i = 1;

                    while (!Request.Url.Segments.ElementAt(i - 1).Equals("medianamik/",
                        StringComparison.OrdinalIgnoreCase))
                    {
                        i++;
                    }

                    var alias = "";

                    if (i < Request.Url.Segments.Length - 1)
                    {
                        alias = Request.Url.Segments.ElementAt(i);
                    }

                    if (alias.Length > 1)
                    {
                        _currentModule = ConfigManager.GetModuleByAlias(alias.Substring(0,
                            alias.Length - 1), CurrentUICulture);
                    }
                }

                return _currentModule;
            }
        }

        private MedianamikPage _currentPage;
        public MedianamikPage CurrentPage
        {
            get
            {
                if (_currentPage == null)
                {
                    var currentNode = SiteMap.CurrentNode;

                    if (currentNode == null)
                    {
                        throw new Exception("Page not found.");
                    }

                    _currentPage = ConfigManager.Get<MedianamikPage>(new Guid(currentNode.Key));

                    if (_currentPage == null)
                    {
                        throw new Exception("Page not found.");
                    }
                }

                return _currentPage;
            }
        }

        private bool _currentMainMenuKeyCheched;
        private Guid? _currentMainMenuKey;
        public Guid? CurrentMainMenuKey
        {
            get
            {
                return _currentMainMenuKeyCheched ? _currentMainMenuKey
                           : (_currentMainMenuKey = GetCurrentMainMenuKey());
            }
        }

        public Guid? GetCurrentMainMenuKey()
        {
            _currentMainMenuKeyCheched = true;
            Guid? result = null;

            if (SiteMap.CurrentNode == null || !StringHelper.IsGuid(SiteMap.CurrentNode.Key, ref result))
                return null;

            var currentNode = SiteMap.CurrentNode;

            while (currentNode.ParentNode != null &&
                StringHelper.IsGuid(currentNode.ParentNode.Key, ref result))
            {
                currentNode = currentNode.ParentNode;
            }

            return result;
        }

        private MasterPage _myMasterPage;
        public MasterPage MyMasterPage
        {
            get
            {
                if (_myMasterPage == null && Master != null)
                {
                    _myMasterPage = Master;

                    while (_myMasterPage.Master != null)
                    {
                        _myMasterPage = _myMasterPage.Master;
                    }
                }

                return _myMasterPage;
            }
        }

        private MedianamikUser _medianamikUser;
        /// <summary>
        /// Usager "Médianamik" présentement connecté
        /// </summary>
        public MedianamikUser MedianamikUser
        {
            get
            {
                if (_medianamikUser == null)
                {
                    _medianamikUser = (MedianamikUser)Membership.GetUser();
                }
                return _medianamikUser;
            }
        }

        public UserProfile MedianamikUserProfile
        {
            get
            {
                return (UserProfile)HttpContext.Current.Profile;
            }
        }

        public virtual string SwitchLangMessage
        {
            get
            {
                return Translator.TranslateJS("Medianamik_ContentManagement", "DefaultSwitchLangMessage");
            }
        }

        protected virtual T GetQueryStringValue<T>(string paramName)
        {
            return Request.QueryString.GetValue<T>(paramName);
        }

        protected static bool IsCurrentUserSuperAdmin
        {
            get
            {
                return Roles.UserIsSA();
            }
        }

        /// <summary>
        /// Méthode de traduction globale
        /// </summary>
        /// <param name="classKey"></param>
        /// <param name="resourceKey"></param>
        /// <returns></returns>
        public string Resources(string classKey, string resourceKey)
        {
            return (String)GetGlobalResourceObject(classKey, resourceKey);
        }

        public void FireCultureChangedEvent()
        {
            OnCultureChanged(new CultureChangedEventArgs(CurrentEditionCulture));
        }

        public string GetCopyright()
        {
            var copyright = Translator.Translate("Medianamik_Global", "Copyright");

            if (String.IsNullOrEmpty(copyright) || (copyright.StartsWith("[") && copyright.EndsWith("]")))
                return "&copy; <a href=\"http://www.absolunet.com/\" target=\"_blank\">Absolunet</a> 2004 - " + DateTime.Now.Year +
                       " Medianamik";

            return copyright;
        }

        /// <summary>
        /// Initilize la culture :
        /// http://weblogs.asp.net/leftslipper/archive/2007/06/19/changing-the-request-culture-for-globalization-and-localization.aspx
        /// </summary>
        protected override void InitializeCulture()
        {
            if (!String.IsNullOrEmpty(Request[PostBackEventTarget])
                && Request[PostBackEventTarget].Equals(ControlIDs.LanguagePickerID)
                && !String.IsNullOrEmpty(Request[PostBackEventArgument]))
            {
                CurrentEditionCulture = CultureInfo.GetCultureInfo(Request[PostBackEventArgument]);
            }

            var profile = (UserProfile)HttpContext.Current.Profile;
            var cultureName = profile.UICultureName;

            if (string.IsNullOrEmpty(cultureName))
            {
                if (User.Identity.IsAuthenticated)
                {
                    cultureName = Config.DefaultUICultureName;
                    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(cultureName);
                }
                else
                {
                    var culture = Session["MyCulture"] as CultureInfo;

                    if (culture == null)
                    {
                        Thread.CurrentThread.CurrentCulture = new CultureInfo(Config.DefaultEditionCultureName);
                        cultureName = Config.DefaultEditionCultureName;
                        Session["MyCulture"] = Thread.CurrentThread.CurrentCulture;
                    }
                    else
                    {
                        cultureName = culture.Name;
                        Thread.CurrentThread.CurrentCulture = culture;
                    }
                }
            }

            Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(cultureName);

            base.InitializeCulture();
        }

        public void Alert(string message)
        {
            ScriptManager.RegisterStartupScript(this, typeof(Page), "RadAlert",
                String.Format("radalert('{0}');", message), true);
        }
    }
}
